﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Data;
using EntityClassGenerator.UserSetting;
using System.Windows.Forms;
using System.IO;

namespace EntityClassGenerator.EntityClassGen
{
    /// <summary>
    /// 本类用于产生Java实体类.
    /// </summary>
    class JavaEntityClassGen:System.IDisposable
    {
        //以下声明代表了实体类的各个部分.
        private string _classHeader ;
        private ArrayList _attrList = new ArrayList();
        private string _structure;
        private ArrayList _accessorList = new ArrayList();
        private string _classEnder = "\n}";

        //下面变量代表了自定义制表符.
        private string _tab=GeneratorTool.GetTabSymbol();

        /// <summary>
        /// 构造方法.
        /// </summary>
        /// <param name="pakName">包名</param>
        /// <param name="refList">引用列表</param>
        /// <param name="claName">类名</param>
        /// <param name="claRemark">类注释</param>
        /// <param name="fieldInfo">字段信息表</param>
        public JavaEntityClassGen(string pakName,string[] refList,string claName,string claRemark,DataTable fieldInfo)
        {
            claName = GeneratorTool.FormatTableOrFieldName(claName);
            claName = GeneratorTool.CapFirstLetter(claName + UserSettings.Postfix);
            this.GetClassHeader(pakName, refList, claName, claRemark);
            this.GetStructureMethod(claName);
            this.GetAttrList(fieldInfo);
            this.GetAccessorList(fieldInfo);
        }

        /// <summary>
        /// 保存实体类.
        /// </summary>
        /// <param name="path">保存目录</param>
        /// <param name="fileName">文件名称</param>
        /// <returns>是否保存成功</returns>
        public bool Save(string path,string fileName)
        {
            fileName = Regex.Replace(fileName,"[^A-Za-z0-9_.]","_");
            bool succ = false;
            try
            {               
                //若没有存在指定的目录,则创建之.
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                //若文件已存在,则删除之.
                if (File.Exists(path + @"\" + fileName))
                {
                    File.Delete(path + @"\" + fileName);
                }

                //创建文件并得到文件流对象.
                FileStream str = new FileStream(path+@"\"+fileName, FileMode.Create);

                //得到写入流对象.
                StreamWriter stream = new StreamWriter(str,System.Text.Encoding.UTF8);              
                
                //将实体类的内容写到文件流中.
                stream.Write(this._classHeader);
                foreach (object attr in this._attrList)
                {
                    stream.Write(attr.ToString());
                }
                stream.Write(this._structure);
                foreach (object accessor in this._accessorList)
                {
                    stream.Write(accessor.ToString());
                }
                stream.Write(this._classEnder);

                //清空并关闭流对象.
                stream.Flush();
                stream.Close();
                succ = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show("保存失败!"+ex.Message);
            }
            return succ;
        }

        /// <summary>
        /// 得到Java实体类的类头.
        /// </summary>
        /// <param name="pakName">包名</param>
        /// <param name="refList">引用列表</param>
        /// <param name="claName">类名</param>
        /// <param name="claRemark">类注释</param>
        private void GetClassHeader(string pakName,string[] refList,string claName,string claRemark)
        {
            string str = "";
            str += GeneratorTool.GetEntityClassHeader(ClassKind.Java);
            str += "\npackage "+pakName+";\n\n";
            for (int i = 0; i < refList.Length; i++)
            {
                str += refList[i]+"\n";
            }
            str += "\n/*"+GeneratorTool.FormatRemark(claRemark)+"*/\n";
            str += "public class "+claName+"{\n";
            this._classHeader=str;
        }

        /// <summary>
        /// 得到Java实体类的属性列表．
        /// </summary>
        /// <param name="fieldInfo">字段信息表</param>
        private void GetAttrList(DataTable fieldInfo)
        {
            Field field = new Field();
            for (int i = 0; i < fieldInfo.Rows.Count; i++)
            { 
                field.name=GeneratorTool.LowerFirstLetter(GeneratorTool.FormatTableOrFieldName(fieldInfo.Rows[i][0].ToString()));
                field.type = fieldInfo.Rows[i][1].ToString();
                field.remark = fieldInfo.Rows[i][2].ToString();
                this._attrList.Add(this.GetAttrItem(field));
            }
        }

        /// <summary>
        /// 得到Java实体类的访问器列表.
        /// </summary>
        /// <param name="fieldInfo">字段信息表</param>
        private void GetAccessorList(DataTable fieldInfo)
        {
            string accessor = "";
            Field field = new Field();
            for (int i = 0; i < fieldInfo.Rows.Count; i++)
            {
                field.name = GeneratorTool.FormatTableOrFieldName(fieldInfo.Rows[i][0].ToString());
                field.type = fieldInfo.Rows[i][1].ToString();
                field.remark = fieldInfo.Rows[i][2].ToString();
                accessor=this.GetReadAccessorCode(field)+this.GetWriteAccessorCode(field);
                this._accessorList.Add(accessor);
            }
        }

        /// <summary>
        /// 根据某个字段信息,得到Java属性项的代码.
        /// </summary>
        /// <param name="field">字段信息</param>
        /// <returns>属性项代码</returns>
        private string GetAttrItem(Field field)
        {            
            return GeneratorTool.ForwardIndentCodeBlock("\nprivate "+field.type+" "+field.name+";",1);
        }

        /// <summary>
        /// 根据类名,得到构造方法的代码.
        /// </summary>
        /// <param name="claName">类名</param>       
        private void GetStructureMethod(string claName)
        { 
            this._structure= GeneratorTool.ForwardIndentCodeBlock("\n\n/*构造方法*/\npublic "+GeneratorTool.CapFirstLetter(claName)+"(){\n}\n",1);
        }

        /// <summary>
        /// 根据字段信息,得到'写'访问器的代码.
        /// </summary>
        /// <param name="field">字段信息</param>
        /// <returns>相应的'写'访问器代码</returns>
        private string GetWriteAccessorCode(Field field)
        {
            string temp = GeneratorTool.Java_FormatAttributeName(field.name);
            return GeneratorTool.ForwardIndentCodeBlock("\n/*设置" + field.remark + "*/\npublic void " + GeneratorTool.GetWriteAccessorName(field.name) + "("+field.type+" "+temp+"){\n"+this._tab+"this."+temp+" = "+temp+";\n}\n",1);
        }

        /// <summary>
        /// 根据字段信息,得到'读'访问器的代码.
        /// </summary>
        /// <param name="field">字段信息</param>
        /// <returns>相应的'读'访问器代码</returns>
        private string GetReadAccessorCode(Field field)
        {
            return GeneratorTool.ForwardIndentCodeBlock("\n/*获取"+field.remark+"*/\npublic "+field.type+" "+GeneratorTool.GetReadAccessorName(field.name)+"() {\n"+this._tab+"return this."+GeneratorTool.LowerFirstLetter(field.name)+";\n}\n",1);
        }

        /// <summary>
        /// 释放本类所占用的资源．
        /// </summary>
        public void Dispose()
        {
            this._accessorList = null;
            this._attrList = null;
            this._classEnder = null;
            this._classHeader = null;
            this._structure = null;
        }

    }
}
